/*
  AdViEmulator - AdventureVision emulator
  Copyright (C) 2012-2013  JustBurn

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <QStyleOptionFrame>
#include "hexioedit.h"

HexIOEdit::HexIOEdit(QWidget *parent) :
	QLineEdit(parent)
{
	_value = 0;
	_minimum = 0;
	_maximum = 255;
	_digits = 2;
	textOption.setTextDirection(layoutDirection());
	textOption.setFlags(QTextOption::IncludeTrailingSpaces);
	textLayout.setTextOption(textOption);
	convertValue();
}

void HexIOEdit::setValue(int value)
{
	if (value > _maximum) value = _maximum;
	if (value < _minimum) value = _minimum;
	_value = value;
	convertValue();
}

int HexIOEdit::value()
{
	return _value;
}

void HexIOEdit::setMinimum(int value)
{
	_minimum = value;
	if (value < _minimum) {
		value = _minimum;
		convertValue();
	}
}

int HexIOEdit::minimum()
{
	return _minimum;
}

void HexIOEdit::setMaximum(int value)
{
	_maximum = value;
	if (value > _maximum) {
		value = _maximum;
		convertValue();
	}
}

int HexIOEdit::maximum()
{
	return _maximum;
}

void HexIOEdit::setDigits(int value)
{
	if (_digits != value) {
		_digits = value;
		convertValue();
	}
}

int HexIOEdit::digits()
{
	return _digits;
}

void HexIOEdit::convertValue(void)
{
	QString str = QString::number(_value, 16).toUpper();
	str = QString().fill('0', _digits - str.length()) + str;
	convValue = str;
	updateTextLayout();
	repaint();
}

void HexIOEdit::updateTextLayout(void)
{
	textLayout.setFont(font());
	textLayout.setText(text());

	textLayout.beginLayout();
	textLayout.createLine();
	textLayout.endLayout();
}

void HexIOEdit::paintEvent(QPaintEvent *)
{
	QPainter p(this);
	QRect r = rect();
	QPalette pal = palette();
	int selstart = this->selectionStart();
	int sellen = this->selectedText().length();
	int cursor = this->cursorPosition();

	QStyleOptionFrame panel;
	initStyleOption(&panel);
	style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
	r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
	p.setClipRect(r);

	p.setPen(pal.text().color());
	QVector<QTextLayout::FormatRange> selections;
	if (selstart != -1) {
		QTextLayout::FormatRange o;
		o.start = selstart;
		o.length = sellen;
		o.format.setBackground(pal.brush(QPalette::Highlight));
		o.format.setForeground(pal.brush(QPalette::HighlightedText));
		selections.append(o);
	}
	textEditPos = QPoint(r.x() + p.fontMetrics().width(convValue + " "), r.y());

	p.setPen(pal.base().color().darker(300));
	QRectF rectTL = QRectF(QPointF(r.left() + 2, r.top() + 1), QPointF(r.right(), r.bottom()));
	p.drawText(rectTL, convValue, textOption);
	p.setPen(pal.text().color());
	QPoint topLeft = QPoint(textEditPos.x() + 2, textEditPos.y() + 1);
	textLayout.draw(&p, topLeft, selections, r);
	if (this->hasFocus())
		textLayout.drawCursor(&p, topLeft, cursor, style()->pixelMetric(QStyle::PM_TextCursorWidth));
}

void HexIOEdit::mousePressEvent(QMouseEvent* e)
{
	QMouseEvent ne = QMouseEvent(e->type(), e->pos() - textEditPos, e->button(), e->buttons(), e->modifiers());
	QLineEdit::mousePressEvent(&ne);
}

void HexIOEdit::mouseMoveEvent(QMouseEvent *e)
{
	QMouseEvent ne = QMouseEvent(e->type(), e->pos() - textEditPos, e->button(), e->buttons(), e->modifiers());
	QLineEdit::mouseMoveEvent(&ne);
}

void HexIOEdit::keyPressEvent(QKeyEvent *e)
{
	switch (e->key()) {
	case Qt::Key_Enter:
	case Qt::Key_Return:
		{
			bool okInt;
			int value = text().toInt(&okInt, 16);
			if (okInt) {
				setValue(value);
				emit valueChanged(_value);
				setText("");
				break;
			}
		}
	}
	QLineEdit::keyPressEvent(e);
	updateTextLayout();
}
